﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using DiscoveryLogic.Analytics.DataObjects;
using DiscoveryLogic.Analytics.DataObjects.Rules;
using DiscoveryLogic.Analytics.DataObjects.Visuals;
using DiscoveryLogic.Common.Utilities;

namespace DiscoveryLogic.Analytics.BusinessLogic.Rules
{
    public class RuleManager
    {
        public static List<RuleBase> GetRulesByType(RuleType ruleType, string iconPath)
        {
            List<RuleBase> rules = new List<RuleBase>();
            string appFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            appFolderPath = Path.Combine(appFolderPath, "Network Data");
            if (!Directory.Exists(appFolderPath))
                Directory.CreateDirectory(appFolderPath);
            string ruleFilePath = Path.Combine(appFolderPath, "Rules.rule");
            if(File.Exists(ruleFilePath))
            {
                XmlDocument xDoc = new XmlDocument();
                xDoc.Load(ruleFilePath);
                XmlNodeList ruleNodes = xDoc.DocumentElement.SelectNodes("Rule");
                if(ruleNodes !=null && ruleNodes.Count>0)
                {
                    foreach(XmlNode ruleNode in ruleNodes)
                    {
                        RuleType ruleType2 =
                            (RuleType) Enum.Parse(
                                           typeof (RuleType),
                                           XmlDataUtil.GetAttributeValue(
                                               ruleNode, "RuleType", RuleType.Import.ToString()));
                        if(ruleType2==ruleType)
                        {
                            switch(ruleType)
                            {
                                case RuleType.Import:
                                    EntityImportRule importRule = 
                                        new EntityImportRule(string.Empty, SetDataSourceType.ExcelFile,
                                            EntityType.Grants, string.Empty);
                                    importRule = (EntityImportRule)importRule.Read(ruleNode);
                                    rules.Add(importRule);
                                    break;
                                case RuleType.Link:
                                    EntityRelationRule rule = 
                                        new EntityRelationRule(string.Empty, string.Empty,
                                            EntityType.Grants, EntityType.Publications, string.Empty);
                                    rule = (EntityRelationRule) rule.Read(ruleNode);
                                    rules.Add(rule);
                                    break;
                                case RuleType.Dedup:
                                    EntityDedupRule dedupRule=
                                        new EntityDedupRule(string.Empty,RuleType.Dedup,SetDataSourceType.XML,
                                            EntityType.Publications,EntityType.Publications,
                                            EntityIcons.DedupRuleIcon);
                                    dedupRule = (EntityDedupRule) dedupRule.Read(ruleNode);
                                    rules.Add(dedupRule);
                                    break;
                                case RuleType.Cluster:
                                    EntityClusterRule clusterRule = 
                                        new EntityClusterRule(string.Empty, SetDataSourceType.XML, EntityType.Document);
                                    clusterRule = (EntityClusterRule) clusterRule.Read(ruleNode);
                                    rules.Add(clusterRule);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }
            }
            

            return rules;
        }

        public static void Save(RuleBase rule)
        {
            string appFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            appFolderPath = Path.Combine(appFolderPath, "Network Data");
            if (!Directory.Exists(appFolderPath))
                Directory.CreateDirectory(appFolderPath);
            string ruleFilePath = Path.Combine(appFolderPath, "Rules.rule");
            XmlDocument xDoc = new XmlDocument();
            XmlNode ruleNode = null;
            if(!File.Exists(ruleFilePath))
            {
                xDoc.LoadXml("<Rules></Rules>");
                XmlNode root = xDoc.DocumentElement;
                ruleNode = XmlDataUtil.AddElement(ref xDoc, root, "Rule");
            }
            else
            {
                xDoc.Load(ruleFilePath);
                ruleNode = xDoc.DocumentElement.SelectSingleNode("Rule[@RuleName=\"" + rule.RuleName + "\"]");
                if(ruleNode==null)
                {
                    XmlNode root = xDoc.DocumentElement;
                    ruleNode = XmlDataUtil.AddElement(ref xDoc, root, "Rule");
                }
                else
                    ruleNode.RemoveAll();
            }
            rule.Save(ref xDoc, ruleNode);
            xDoc.Save(ruleFilePath);

        }

        public static void DeleteRule(RuleBase rule)
        {
            string appFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            appFolderPath = Path.Combine(appFolderPath, "Network Data");
            if (!Directory.Exists(appFolderPath))
                Directory.CreateDirectory(appFolderPath);
            string ruleFilePath = Path.Combine(appFolderPath, "Rules.rule");
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(ruleFilePath);
            XmlNode ruleNode = xDoc.DocumentElement.SelectSingleNode("Rule[@RuleName=\"" + rule.RuleName + "\"]");
            if (ruleNode != null)
            {
                ruleNode.ParentNode.RemoveChild(ruleNode);
            }
            xDoc.Save(ruleFilePath);
        }
    }
}
